package com.mtons.mblog.modules.service.impl;

import com.mtons.mblog.base.lang.EntityStatus;
import com.mtons.mblog.base.lang.MemoryType;
import com.mtons.mblog.base.utils.BeanMapUtils;
import com.mtons.mblog.base.utils.CommonUtils;
import com.mtons.mblog.modules.data.LearnPlanSetVO;
import com.mtons.mblog.modules.entity.LearnPlanSet;
import com.mtons.mblog.modules.repository.LearnPlanSetRepository;
import com.mtons.mblog.modules.service.LearnPlanSetService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author Tison
 */
@Service
public class LearnPlanSetServiceImpl implements LearnPlanSetService {

    @Resource
    private LearnPlanSetRepository learnPlanSetRepository;


    public LearnPlanSet save(LearnPlanSet obj) {
        return learnPlanSetRepository.save(obj);
    }


    @Transactional
    public List<LearnPlanSet> saveAll(Iterable<LearnPlanSet> list) {
        return learnPlanSetRepository.saveAll(list);
    }


    public LearnPlanSet getOne(String id) {
        return learnPlanSetRepository.getOne(id);
    }


    public LearnPlanSet findById(String id) {
        Optional<LearnPlanSet> obj = learnPlanSetRepository.findById(id);
        return obj.orElse(null);
    }


    public void deleteById(String id) {
        learnPlanSetRepository.deleteById(id);
    }


    @Transactional
    public void deleteAll(List list) {
        learnPlanSetRepository.deleteAll(list);
    }


    public void delete(LearnPlanSet obj) {
        learnPlanSetRepository.delete(obj);
    }


    public boolean existsById(String id) {
        return learnPlanSetRepository.existsById(id);
    }


    public long count() {
        return learnPlanSetRepository.count();
    }


    public List<LearnPlanSet> findAll() {
        return learnPlanSetRepository.findAll();
    }


    public List<LearnPlanSet> findAll(LearnPlanSet obj) {
        List<LearnPlanSet> list = learnPlanSetRepository.findAll(Example.of(obj));
        return list == null || list.size() < 1 ? null : list;
    }


    public List<LearnPlanSet> findAll(Sort sort) {
        return learnPlanSetRepository.findAll(sort);
    }


    public List<LearnPlanSet> findAllById(Iterable<String> ids) {
        return learnPlanSetRepository.findAllById(ids);
    }


    public List<LearnPlanSet> findAll(Example<LearnPlanSet> e) {
        return learnPlanSetRepository.findAll(e);
    }


    public List<LearnPlanSet> findAll(Example<LearnPlanSet> e, Sort sort) {
        return learnPlanSetRepository.findAll(e, sort);
    }


    public Page<LearnPlanSet> findAll(Pageable page) {
        return learnPlanSetRepository.findAll(page);
    }


    public Page<LearnPlanSet> findAll(Example<LearnPlanSet> e, Pageable page) {
        return learnPlanSetRepository.findAll(e, page);
    }


    public Page<LearnPlanSet> findAll(LearnPlanSet obj, Pageable page) {
        return learnPlanSetRepository.findAll(Example.of(obj), page);
    }


    @Override
    @Transactional
    public List<LearnPlanSetVO> queryPlanSettings(long userId) {
        final LearnPlanSet learnPlanSet = new LearnPlanSet();
        learnPlanSet.setCreateUser(userId);
        List<LearnPlanSet> planSets = learnPlanSetRepository.findAll(Example.of(learnPlanSet));
        if (CollectionUtils.isEmpty(planSets)) {
            planSets = initPlanSet(userId);
        }
        final List<LearnPlanSet> learnPlanSets = planSets.stream().sorted((v1, v2) -> {
            final int result = v1.getPlanCode().compareTo(v2.getPlanCode());
            return result;
        }).collect(Collectors.toList());
        List<LearnPlanSetVO> planSetVOList = new ArrayList<>(learnPlanSets.size());
        learnPlanSets.forEach(planSet -> {
            final LearnPlanSetVO planSetVO = BeanMapUtils.copy(planSet);
            final String planCode = planSetVO.getPlanCode();
            final MemoryType memoryType = MemoryType.getMemoryByType(planCode);
            planSetVO.setTimeShow(memoryType.getTimeShow());
            planSetVOList.add(planSetVO);
        });

        return planSetVOList;
    }

    @Override
    @Transactional
    public void updateStatus(String id, String status) {
        LearnPlanSet learnPlanSet = learnPlanSetRepository.findById(id).get();
        if (status.equals(learnPlanSet.getStatus())) {
            return;
        }
        learnPlanSet.setStatus(status);
        learnPlanSetRepository.save(learnPlanSet);
    }

    private List<LearnPlanSet> initPlanSet(long userId) {
        List<LearnPlanSet> planSets = new ArrayList<>();
        final MemoryType[] values = MemoryType.values();
        final Date nowTime = CommonUtils.getNowTime();
        for (int i = 0; i < values.length; i++) {
            final MemoryType memoryType = values[i];
            LearnPlanSet planSet = new LearnPlanSet();
            planSet.setId(CommonUtils.getUUID());
            planSet.setPlanCode(memoryType.getType());
            planSet.setPlanName(memoryType.getName());
            planSet.setPlanTime(memoryType.getSeconds());
            planSet.setStatus(EntityStatus.IS_VALID);
            planSet.setCreateUser(userId);
            planSet.setCreateTime(nowTime);
            planSets.add(planSet);
        }
        return saveAll(planSets);
    }
}
